import serial
import serial.tools.list_ports
from data_manage import SEND_TYPE
# from manager.Common import *
import threading


class ComManager(object):
    _instance_lock = threading.Lock()
    _first_init = True

    def __init__(self):
        if self._first_init:
            self._first_init = False
            self.com_port = None
            # self.dict_sensor = {}
        pass

    def __del__(self):
        pass

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            with ComManager._instance_lock:
                if not hasattr(cls, '_instance'):
                    ComManager._instance = super().__new__(cls)
        return ComManager._instance

    def init_com(self, com, baud, parity, stop, data):
        self.com_port = serial.Serial(com, baud, data, parity, stop)

    @staticmethod
    def get_com_port():
        port_list = list(serial.tools.list_ports.comports())
        device_dict = {}
        for i in range(0, len(port_list)):
            device_dict[port_list[i].name] = port_list[i].device
            print(port_list[i].name)
        return device_dict

    def open_com_port(self):
        if not self.com_port.is_open:
            self.com_port.open()
        pass

    def check_com_open(self):
        return self.com_port.is_open

    def close_com_port(self):
        if self.com_port.is_open:
            self.com_port.close()
            self.com_port = None
        pass

    def receive_data(self, way):
        try:
            if self.com_port.in_waiting:
                if way == 0:
                    return self.com_port.read(self.com_port.in_waiting)
                elif way == 1:
                    return self.com_port.readall().decode()
            else:
                return ''
        except Exception as e:
            print("异常报错", e)

    def read_line(self):
        return self.com_port.readline()

    def send_data(self, send_type, data):
        if self.com_port is None:
            return
        if send_type == SEND_TYPE.HEX_SEND:
            hex_data = bytes.fromhex(data)
            self.com_port.write(hex_data)
        else:
            self.com_port.write(data.encode())
        print('send data: ', data)

    @staticmethod
    def change_parity(str_parity):
        parity = ''
        if str_parity == "None":
            parity = serial.PARITY_NONE
        elif str_parity == "Odd":
            parity = serial.PARITY_NAMES.PARITY_ODD
        elif str_parity == "Even":
            parity = serial.PARITY_NAMES.PARITY_EVEN
        return parity

    # def data_paste(self, data: bytes):
    #     Common.data_paste(data, self.dict_sensor)
    #     return self.dict_sensor

    @staticmethod
    def get_rec_data(str_command):
        b_loop = True
        i_connect = 0
        data = ''
        # while b_loop:
        #     ComManager().send_data(SEND_TYPE.HEX_SEND, str_command)
        #     c_info = ComManager().receive_data(0)
        #     print('receive:', c_info)
        #     if c_info:
        #         # receive data format is valid
        #         index = c_info.find(b'\xa5')
        #         if Common().rev_format_valid(index, c_info):
        #             data = c_info
        #             i_connect = 10
        #         else:
        #             i_connect += 1
        #     else:
        #         i_connect += 1
        #         time.sleep(0.5)
        #     if i_connect >= 10:
        #         b_loop = False
        return data
